package ldh.im.rpc.connection.socket;

import ldh.im.rpc.buffer.RpcBuffer;
import ldh.im.rpc.buffer.RpcByteBuffer;
import ldh.im.rpc.codec.RpcDataCodec;
import ldh.im.rpc.codec.RpcStupidBearBinaryCodec;
import ldh.im.rpc.config.RpcConfig;
import ldh.im.rpc.dto.RpcData;

import java.net.Socket;

public class RpcSocketHandle implements Runnable {

    private Socket socket;
    private RpcConfig rpcConfig;

    private RpcBuffer rpcBuffer;

    private volatile boolean isClosed = false;
    private RpcDataSocketChannel rpcChannel;
    private RpcDataCodec rpcDataCodec;

    public RpcSocketHandle(RpcConfig rpcConfig, Socket socket) {
        this.rpcConfig = rpcConfig;
        this.socket = socket;
        rpcBuffer = new RpcByteBuffer(1024 * 10);

        rpcDataCodec = new RpcDataCodec(rpcConfig, new RpcStupidBearBinaryCodec());
        rpcChannel = new RpcDataSocketChannel(rpcBuffer, socket, rpcDataCodec);
    }

    @Override
    public void run() {
        while(!isClosed) {
            rpcChannel.read();
            int dataLength = rpcBuffer.readInt();
            int readIndex = rpcBuffer.getReadIdx();
            rpcBuffer.markReadIdx();
            if (dataLength <= rpcBuffer.readable()) {
                decode();
            }
            if (rpcBuffer.getReadIdx() != readIndex + dataLength) {
                rpcBuffer.resetMarkReadIdx();
                rpcBuffer.skip(dataLength);
            }

            rpcBuffer.discard();
        }
    }

    private <T>RpcData<T> decode() {
        RpcData rpcData = rpcDataCodec.decode(rpcBuffer);
        // todo
        return rpcData;
    }
}
